#ifndef TSETTINGS_H
#define TSETTINGS_H

#ifdef SETTINGS_USE_DBC
#include <QSettings>
#include <QStack>

class DBTabSettings;
class TSettings : public QObject
{
    Q_OBJECT

public:

    enum Status {
        NoError = 0,
        AccessError,
        FormatError
    };
//#ifndef QT_NO_QOBJECT
//    Q_ENUM(Status)
//#endif

    enum Format {
        NativeFormat,
        IniFormat,

#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC)
        Registry32Format,
        Registry64Format,
#endif

        InvalidFormat = 16,
        CustomFormat1,
        CustomFormat2,
        CustomFormat3,
        CustomFormat4,
        CustomFormat5,
        CustomFormat6,
        CustomFormat7,
        CustomFormat8,
        CustomFormat9,
        CustomFormat10,
        CustomFormat11,
        CustomFormat12,
        CustomFormat13,
        CustomFormat14,
        CustomFormat15,
        CustomFormat16
    };
#ifndef QT_NO_QOBJECT
    //Q_ENUM(Format)
#endif

    enum Scope {
        UserScope,
        SystemScope
    };
#ifndef QT_NO_QOBJECT
    //Q_ENUM(Scope)
#endif

//    explicit TSettings(const QString &organization,
//                       const QString &application = QString(), QObject *parent = nullptr);
//    TSettings(Scope scope, const QString &organization,
//              const QString &application = QString(), QObject *parent = nullptr);
//    TSettings(Format format, Scope scope, const QString &organization,
//              const QString &application = QString(), QObject *parent = nullptr);
    TSettings(const QString &fileName, Format format=IniFormat, QObject *parent = nullptr);
//    explicit TSettings(QObject *parent = nullptr);
//    explicit TSettings(Scope scope, QObject *parent = nullptr);

    ~TSettings();

    void clear();
//    void sync();
//    Status status() const;
//    bool isAtomicSyncRequired() const;
//    void setAtomicSyncRequired(bool enable);

    void beginGroup(const QString &prefix);
    void endGroup();
    QString group() const;

    int beginReadArray(const QString &prefix);
    void beginWriteArray(const QString &prefix, int size = -1);
    void endArray();
    void setArrayIndex(int i);

    QStringList allKeys() const;
    QStringList childKeys() const;
    QStringList childGroups() const;
    bool isWritable() const;

    void setValue(const QString &key, const QVariant &value);
    QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;

    void remove(const QString &key);
    bool contains(const QString &key) const;

    void setFallbacksEnabled(bool b);
    bool fallbacksEnabled() const;

    QString fileName() const;
    Format format() const;
    Scope scope() const;
    QString organizationName() const;
    QString applicationName() const;

//#if QT_CONFIG(textcodec)
//    void setIniCodec(QTextCodec *codec);
//    void setIniCodec(const char *codecName);
//    QTextCodec *iniCodec() const;
//#endif

    static void setDefaultFormat(Format format);
    static Format defaultFormat();
//#if QT_DEPRECATED_SINCE(5, 13)
//    QT_DEPRECATED_X("Use QSettings::setPath() instead")
//    static void setSystemIniPath(const QString &dir);
//    QT_DEPRECATED_X("Use QSettings::setPath() instead")
//    static void setUserIniPath(const QString &dir);
//#endif
    static void setPath(Format format, Scope scope, const QString &path);

    typedef QMap<QString, QVariant> SettingsMap;
    typedef bool (*ReadFunc)(QIODevice &device, SettingsMap &map);
    typedef bool (*WriteFunc)(QIODevice &device, const SettingsMap &map);

    static Format registerFormat(const QString &extension, ReadFunc readFunc, WriteFunc writeFunc,
                                 Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive);


private:
    enum KeyType{
        KT_GROUP,
        KT_ARRAY,
        KT_INDEX,
    };
    struct KeyInfo{
        QString key;
        KeyType ktype;
    };
    Q_DISABLE_COPY(TSettings)
    QString mPreName;
    int mArrayIndex;
    int mArrayDepth;
    QStack<KeyInfo > mKeyQuenu;
    DBTabSettings *mDBTabSettings;

};
#else
#include <QSettings>
#define TSettings QSettings

#endif
#endif // TSETTINGS_H
